home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / langs / sozo2 / scsrc20.lzh / JAS.LZH / GEN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-22  |  10.2 KB  |  466 lines

  1.  
  2. /*
  3.  * Copyright (c) 1988,1991 by Sozobon, Limited.  Author: Joseph M Treat
  4.  *
  5.  * Permission is granted to anyone to use this software for any purpose
  6.  * on any computer system, and to redistribute it freely, with the
  7.  * following restrictions:
  8.  * 1) No charge may be made other than reasonable charges for reproduction.
  9.  * 2) Modified versions must be clearly marked as such.
  10.  * 3) The authors are not responsible for any harmful consequences
  11.  *    of using this software, even if they result from defects in it.
  12.  */
  13.  
  14. #include "jas.h"
  15.  
  16. geninst( sp )
  17.     STMT *sp;
  18. {
  19.     register OPERAND *op;
  20.     register char *cp;
  21.     register short nbits = 0;
  22.     register long fill = 0L;
  23.     register short emode, ereg;
  24.     OPERAND *eff[2];
  25.     int which, do_immediate = 0;
  26.     CBUF *cbp;
  27.     extern int line;
  28.     extern long newdot;
  29.     extern Optimize;
  30.     extern CBUF *generate();
  31.  
  32.     findinst( sp );
  33.     eff[0] = eff[1] = (OPERAND *) NULL;
  34.  
  35.     if ( sp->op0 && sp->op0->mode == O_IMM )
  36.         do_immediate = 1;
  37.  
  38.     for ( cp = sp->inst->format; *cp; cp++ ) {
  39.         if ( *cp == 'o' ) {
  40.             do {
  41.                 cp++;
  42.                 fill = ( fill << 3 ) | ( *cp - '0' );
  43.                 nbits += 3;
  44.             } while ( cp[1] >= '0' && cp[1] <= '7' );
  45.         } else if ( *cp == 'x' ) {
  46.             do {
  47.                 cp++;
  48.                 if ( *cp <= '9' )
  49.                     fill = ( fill << 4 ) | ( *cp - '0' );
  50.                 else
  51.                     fill = ( fill << 4 ) | (*cp - 'a' + 10);
  52.                 nbits += 4;
  53.             } while ( (cp[1] >= '0' && cp[1] <= '9') ||
  54.                         (cp[1] >= 'a' && cp[1] <= 'f'));
  55.  
  56.         } else if ( *cp == '0' ) {
  57.             fill = ( fill << 1 );
  58.             nbits++;
  59.         } else if ( *cp == '1' ) {
  60.             fill = ( fill << 1 ) | 1;
  61.             nbits++;
  62.         } else if ( *cp == '$' ) {
  63.             switch ( *++cp ) {
  64.             case 's':
  65.                 fill = ( fill << 2 ) |
  66.                         ( ( sp->misc & (S_BWL) ) >> 1 );
  67.                 nbits += 2;
  68.                 break;
  69.             case 'c':
  70.                 fill = ( fill << 4 ) | ( sp->misc >> 4 );
  71.                 nbits += 4;
  72.                 break;
  73.             case 'd':
  74.                 fill = ( fill << 1 ) |
  75.                         ( ( sp->misc & 0x8 ) >> 3 );
  76.                 nbits++;
  77.                 break;
  78.             }
  79.         } else if ( *cp == '%' ) {
  80.             OPERAND *mp;
  81.  
  82.             cp++;
  83.             if ( *cp == '0' ) {
  84.                 which = 0;
  85.                 op = sp->op0;
  86.                 cp++;
  87.             } else if ( *cp == '1' ) {
  88.                 which = 1;
  89.                 op = sp->op1;
  90.                 cp++;
  91.             } else if ( *cp >= 'A' && *cp <= 'Z' ) {
  92.                 which = 1;
  93.                 op = sp->op1;
  94.             } else /* if ( *cp >= 'a' && *cp <= 'z' ) */ {
  95.                 which = 0;
  96.                 op = sp->op0;
  97.             }
  98.  
  99.             switch ( *cp ) {
  100.             case 'r':
  101.                 fill = ( fill << 3 ) | (op->reg & 0x7 );
  102.                 nbits += 3;
  103.                 break;
  104.             case 'q':
  105.                 fill = ( fill << 3 ) | (op->expr.value & 0x7);
  106.                 nbits += 3;
  107.                 do_immediate = 0;
  108.                 break;
  109.             case 'k':
  110.                 fill = ( fill << 8 ) | (op->expr.value & 0xff);
  111.                 nbits += 8;
  112.                 do_immediate = 0;
  113.                 break;
  114.             case 'v':
  115.                 fill = ( fill << 4 ) | (op->expr.value & 0x0f);
  116.                 nbits += 4;
  117.                 do_immediate = 0;
  118.                 break;
  119.             case 'm':
  120.                 if ( nbits % 8 )
  121.                     error( line, "internal alignment" );
  122.                 generate( nbits, GENSTMT, fill, (SYM *) NULL );
  123.                 nbits = 0;
  124.                 fill = 0L;
  125.                 if ( op->mode == O_DN || op->mode == O_AN )
  126.                     op->expr.value = 1L << op->reg;
  127.                 op->mode = O_REGS;
  128.                 mp = ( which == 0 ) ? sp->op1 : sp->op0;
  129.                 if ( mp->mode == O_PRE ) {
  130.                     /*
  131.                      * we must reverse the bits !GAG!
  132.                      */
  133.                     int i, k;
  134.  
  135.                     k = op->expr.value;
  136.                     for ( i = 0; i < 16; i++ ) {
  137.                         fill <<= 1;
  138.                         if ( k & 1 )
  139.                             fill |= 1;
  140.                         k >>= 1;
  141.                     }
  142.                     generate( 16, GENVALUE, fill,
  143.                                 (SYM *) NULL );
  144.                     fill = 0L;
  145.                 } else {
  146.                     generate( 16, GENVALUE, op->expr.value,
  147.                                 (SYM *) NULL );
  148.                 }
  149.                 break;
  150.             case 'd':
  151.                 if (! Optimize ) {
  152.                     fill <<= 8;
  153.                     nbits += 8;
  154.                     if ( nbits % 8 )
  155.                         error( line,
  156.                             "internal alignment" );
  157.                     generate( nbits, GENSTMT, fill,
  158.                                 (SYM *) NULL);
  159.                     nbits = 0;
  160.                     fill = 0L;
  161.                     generate( 16, GENPCREL, op->expr.value,
  162.                                 op->expr.psym);
  163.                     break;
  164.                 }
  165.                 if ( nbits != 8 )
  166.                     error( line, "internal alignment" );
  167.                 cbp = generate(8, GENBRNCH, fill, (SYM *) NULL);
  168.                 nbits = 0;
  169.                 fill = 0L;
  170.  
  171.                 generate( 8, GENPCREL, op->expr.value,
  172.                                 op->expr.psym);
  173.                 add_brnch( cbp, newdot );
  174.                 break;
  175.             case 'D':
  176.                 if ( nbits % 8 )
  177.                     error( line, "internal alignment" );
  178.                 generate( nbits, GENSTMT, fill, (SYM *) NULL );
  179.                 nbits = 0;
  180.                 fill = 0L;
  181.                 generate( 16, GENPCREL, op->expr.value,
  182.                                 op->expr.psym);
  183.                 break;
  184.             case 'L':
  185.                 if ( nbits % 8 )
  186.                     error( line, "internal alignment" );
  187.                 generate( nbits, GENSTMT, fill, (SYM *) NULL );
  188.                 nbits = 0;
  189.                 fill = 0L;
  190.                 generate( 16, GENVALUE, op->expr.value,
  191.                                 (SYM *) NULL );
  192.                 do_immediate = 0;
  193.                 break;
  194.             case 'f':
  195.             case 'e':
  196.                 emode = ereg = 0;
  197.                 switch ( op->mode ) {
  198.                 case O_DN:
  199.                     emode = 0x0;
  200.                     ereg = op->reg & 0x7;
  201.                     break;
  202.                 case O_AN:
  203.                     emode = 0x1;
  204.                     ereg = op->reg & 0x7;
  205.                     break;
  206.                 case O_INDR:
  207.                     emode = 0x2;
  208.                     ereg = op->reg & 0x7;
  209.                     break;
  210.                 case O_POST:
  211.                     emode = 0x3;
  212.                     ereg = op->reg & 0x7;
  213.                     break;
  214.                 case O_PRE:
  215.                     emode = 0x4;
  216.                     ereg = op->reg & 0x7;
  217.                     break;
  218.                 case O_DISP:
  219.                     emode = 0x5;
  220.                     ereg = op->reg & 0x7;
  221.                     eff[which] = op;
  222.                     break;
  223.                 case O_INDX:
  224.                     emode = 0x6;
  225.                     ereg = op->reg & 0x7;
  226.                     eff[which] = op;
  227.                     break;
  228. #ifdef MINIX
  229.                 case O_SABS:
  230.                     emode = 0x7;
  231.                     ereg = 0x0;
  232.                     eff[which] = op;
  233.                     break;
  234. #endif
  235.                 case O_ABS:
  236.                     emode = 0x7;
  237.                     ereg = 0x1;
  238.                     eff[which] = op;
  239.                     break;
  240.                 case O_PCRL:
  241.                     emode = 0x7;
  242.                     ereg = 0x2;
  243.                     eff[which] = op;
  244.                     break;
  245.                 case O_PCIX:
  246.                     emode = 0x7;
  247.                     ereg = 0x3;
  248.                     eff[which] = op;
  249.                     break;
  250.                 case O_IMM:
  251.                     emode = 0x7;
  252.                     ereg = 0x4;
  253.                     break;
  254.                 }
  255.                 if ( *cp == 'e' ) {
  256.                     fill = ( fill << 3 ) | emode;
  257.                     fill = ( fill << 3 ) | ereg;
  258.                 } else {
  259.                     fill = ( fill << 3 ) | ereg;
  260.                     fill = ( fill << 3 ) | emode;
  261.                 }
  262.                 nbits += 6;
  263.                 break;
  264.             }
  265.         } 
  266.     }
  267.     if ( nbits % 8 )
  268.         error( line, "internal alignment" );
  269.     if ( nbits ) {
  270.         generate( nbits, GENSTMT, fill, (SYM *) NULL );
  271.         nbits = 0;
  272.     }
  273.     fill = 0L;
  274.     if ( do_immediate ) {
  275.         int size;
  276.         op = sp->op0;
  277.  
  278.         size = sp->misc & (S_BWL);
  279.         if ( size == S_B ) {
  280.             generate( 8, GENVALUE, 0L, (SYM *) NULL );
  281.         }
  282.         generate( size << 3, GENRELOC, op->expr.value, op->expr.psym );
  283.     }
  284.     for ( which = 0; which <= 1; which++ ) {
  285.         if ( eff[which] == (OPERAND *) NULL )
  286.             continue;
  287.         op = eff[which];
  288.         switch ( op->mode ) {
  289.         case O_DISP:
  290.             generate( 16, GENRELOC, op->expr.value, op->expr.psym );
  291.             break;
  292.         case O_INDX:
  293.             fill = op->inx & 0x0f;
  294.             fill = ( fill << 4 ) | ((op->inx & 0x10) >> 1);
  295.             generate(8, GENVALUE, fill, (SYM *) NULL );
  296.             generate( 8, GENRELOC, op->expr.value, op->expr.psym );
  297.             break;
  298. #ifdef MINIX
  299.         case O_SABS:
  300.             if ( sp->inst->flags & F_PC )
  301.                 generate( 16, GENPCREL, op->expr.value,
  302.                                 op->expr.psym );
  303.             else
  304.                 generate( 16, GENRELOC, op->expr.value,
  305.                                 op->expr.psym );
  306.             break;
  307. #endif
  308.         case O_ABS:
  309.             if ( sp->inst->flags & F_PC )
  310.                 generate( 16, GENPCREL, op->expr.value,
  311.                                 op->expr.psym );
  312.             else
  313.                 generate( 32, GENRELOC, op->expr.value,
  314.                                 op->expr.psym );
  315.             break;
  316.         case O_PCRL:
  317. #ifdef MINIX
  318.             if ( op->expr.psym )
  319.                 generate( 16, GENPCREL, op->expr.value,
  320.                                 op->expr.psym );
  321.             else
  322.                 generate( 16, GENVALUE, op->expr.value,
  323.                                 (SYM *) NULL );
  324. #else
  325.             generate( 16, GENVALUE, op->expr.value, (SYM *) NULL );
  326. #endif
  327.             break;
  328.         case O_PCIX:
  329.             fill = op->inx & 0x0f;
  330.             fill = ( fill << 4 ) | ((op->inx & 0x10) >> 1);
  331.             generate(8, GENVALUE, fill, (SYM *) NULL );
  332. #ifdef MINIX
  333.             if ( op->expr.psym )
  334.                 generate( 8, GENPCREL, op->expr.value,
  335.                                 op->expr.psym );
  336.             else
  337.                 generate( 8, GENVALUE, op->expr.value,
  338.                                 (SYM *) NULL );
  339. #else
  340.             generate( 8, GENVALUE, op->expr.value, (SYM *) NULL );
  341. #endif
  342.             break;
  343.         }
  344.     }
  345. }
  346.  
  347. findinst( sp )
  348.     STMT *sp;
  349. {
  350.     register INST *ip;
  351.     register INST *jp;
  352.  
  353.     ip = sp->inst;
  354.     for ( ; ; ) {
  355.         if (! inst_ok( sp ) ) {
  356.             return;
  357.         }
  358.         jp = ip+1;
  359.         if (! strcmp( jp->mnemon, ip->mnemon ) ) {
  360.             sp->inst = ip = jp;
  361.             continue;
  362.         }
  363.         break;
  364.     }
  365.     Yerror( "illegal instruction" );
  366. }
  367.  
  368. inst_ok( sp )
  369.     register STMT *sp;
  370. {
  371.     register INST *ip = sp->inst;
  372.     register unsigned short size;
  373.     extern Optimize;
  374.  
  375.     if (! Optimize ) {
  376.         /*
  377.          * if we're not optimizing, don't change jsr's to bsr's
  378.          */
  379.         if (! strncmp( ip->mnemon, "jsr", 3 ) )
  380.             if (! strncmp( ip->format, "x61", 3 ) )
  381.                 return -18;
  382.     }
  383.  
  384.     if ( ip->op0 != O_NONE && sp->op0 == (OPERAND *) NULL )
  385.         return -1;
  386.     if ( ip->op1 != O_NONE && sp->op1 == (OPERAND *) NULL )
  387.         return -2;
  388.     if ( sp->op1 && ip->op1 == O_NONE )
  389.         return -3;
  390.     if ( sp->op0 ) {
  391.         if ( ip->op0 == O_NONE )
  392.             return -4;
  393.         if ( ( sp->op0->mode & ip->op0 ) != sp->op0->mode )
  394.             return -5;
  395.     }
  396.     if ( sp->op1 ) {
  397.         if ( ip->op1 == O_NONE )
  398.             return -6;
  399.         if ( ( sp->op1->mode & ip->op1 ) != sp->op1->mode )
  400.             return -7;
  401.     }
  402.     size = sp->misc & (S_BWL);
  403.     if ( ( size & ip->size ) != size )
  404.         return -8;
  405.     if ( ip->flags & F_Q ) {
  406.         long val = sp->op0->expr.value;
  407.  
  408.         if ( sp->op0->expr.psym )
  409.             return -9;
  410.         if ( val < 1 || val > 8 )
  411.             return -10;
  412.     }
  413.     if ( ip->flags & F_MQ ) {
  414.         long val = sp->op0->expr.value;
  415.  
  416.         if ( sp->op0->expr.psym )
  417.             return -11;
  418.         if ( val < -128 || val > 127 )
  419.             return -12;
  420.     }
  421.     if ( ip->flags & F_TV ) {
  422.         long val = sp->op0->expr.value;
  423.  
  424.         if ( sp->op0->expr.psym )
  425.             return -13;
  426.         if ( val < 0 || val > 15 )
  427.             return -14;
  428.     }
  429.     if ( ip->flags & F_TXT ) {
  430.         OPERAND *op = sp->op0;
  431.  
  432.         if ( op->mode == O_DN ) /* the db$c instruction */
  433.             op = sp->op1;
  434.         switch ( op->mode ) {
  435.         case O_DISP: case O_INDX:
  436.             if ( op->expr.psym ) {
  437.                 switch ( op->expr.psym->flags & SEGMT ) {
  438.                 case 0: case TXT:
  439.                     break;
  440.                 default:
  441.                     return -15;
  442.                 }
  443.             }
  444.             break;
  445.         case O_ABS:
  446.             if ( op->expr.psym == (SYM *) NULL )
  447.                 return -16;
  448.             switch ( op->expr.psym->flags & SEGMT ) {
  449.             case 0: case TXT:
  450.                 break;
  451.             default:
  452.                 return -17;
  453.             }
  454.             break;
  455.         }
  456.     }
  457.  
  458.     /*
  459.      * set the default size, if none is specified
  460.      */
  461.     if ( size == 0 )
  462.         sp->misc |= ( ip->flags & (S_BWL) );
  463.  
  464.     return 0;
  465. }
  466.